#include "SptProject.h"
using namespace spt;

bool8 spt::WRLock::WLock()
{
	if (write_cnt)
	{
		return 0;
	}

	if (is_write)
	{
		return 0;
	}
	
	if (read_cnt)
	{
		is_rdirty = 1;
	}
	is_write = write_cnt =1;

	return bool8(1);
}

bool8 spt::WRLock::RLock()
{
	if (is_write)
	{
		return 0;
	}

	if (write_cnt)
	{
		return 0;
	}
	read_cnt++;
	return bool8(1);
}

bool8 spt::WRLock::RDirty()
{
	return bool8(is_rdirty);
}

void spt::WRLock::WUnLock()
{
	is_write = write_cnt = 0;
}

void spt::WRLock::RUnLock()
{
	if (read_cnt)
	{
		read_cnt--;
	}
	else
	{
		is_rdirty = 0;
	}
}

void spt::WRLock::UnLock()
{
	is_write = read_cnt = write_cnt = 0;
}

spt::AutoLock::AutoLock(WRLock& Lock):lock(Lock)
{
	is_write = is_read = 0;
}

spt::AutoLock::~AutoLock()
{
	WUnLock();
	RUnLock();
}

bool8 spt::AutoLock::RDirty()
{
	return bool8(lock.RDirty());
}

bool8 spt::AutoLock::WLock()
{
	if (is_write)
	{
		return 0;
	}
	return is_write = lock.WLock();
}

void spt::AutoLock::WUnLock()
{
	if (is_write)
	{
		lock.WUnLock();
	}
}

bool8 spt::AutoLock::RLock()
{
	return is_read = lock.RLock();
}

void spt::AutoLock::RUnLock()
{
	if (is_read)
	{
		lock.RUnLock();
	}
}
